package org.frog.sgs.server.game;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Random;

import org.frog.sgs.card.basic.Basic;
import org.frog.sgs.card.general.General;
import org.frog.sgs.card.general.shu.base.LiuBei;
import org.frog.sgs.card.general.wei.base.CaoCao;
import org.frog.sgs.card.general.wu.base.SunQuan;
import org.frog.sgs.data.GameDataManager;

/**
 * @author duanxiangqi
 * @date 2012-10-20
 */
@SuppressWarnings("unchecked")
public class ServerCardManager {

	private ServerInstance instance;

	// 牌堆
	private List<Basic> basics = new ArrayList<Basic>();

	// 弃牌堆
	private List<Basic> recycleBin = new ArrayList<Basic>();

	private List<General> generals = new ArrayList<General>();

	public void init() {
		basics = GameDataManager.instance.getAllBasicsCopy();
		generals = GameDataManager.instance.getAllGeneralsCopy();
		shuffleBasic();
	}

	/**
	 * 随机打乱牌堆
	 */
	public void shuffleBasic() {
		Collections.shuffle(basics);
	}

	/**
	 * 获取并删除一个指定类型的牌
	 * 
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	public <T> T getOutBasicByType(Class<? extends Basic> clazz) {
		for (Basic basic : basics) {
			if (basic.getClass() == clazz) {
				basics.remove(basic);
				return (T) basic;
			}
		}
		return null;
	}

	/**
	 * 从上面获取若干张牌
	 */
	public List<Basic> getOutBasics(int num) {
		List<Basic> basics = new ArrayList<Basic>();
		for (int i = 0; i < num; i++) {
			Basic basic = getOutOneBasic();
			if (basic != null) {
				basics.add(basic);
			}
		}
		return basics;
	}

	/**
	 * 把若干牌放到牌堆上面
	 */
	public void putBasic2top(Basic basic) {
		basic.setCharacter(null);
		basics.add(0, basic);
	}

	/**
	 * 把若干牌放到牌堆上面
	 */
	public void putBasic2top(List<Basic> basics) {
		Collections.reverse(basics);
		for (Basic basic : basics) {
			putBasic2top(basic);
		}
	}

	/**
	 * 把若干牌放到牌堆次下面
	 */
	public void putBasic2bottom(Basic basic) {
		basic.setCharacter(null);
		basics.add(basic);
	}

	/**
	 * 把若干牌放到牌堆次下面
	 */
	public void putBasic2bottom(List<Basic> basics) {
		for (Basic basic : basics) {
			putBasic2bottom(basic);
		}
	}

	/**
	 * 把若干张牌丢到弃牌堆
	 */
	public void putBasic2recycle(Basic basic) {
		basic.setCharacter(null);
		recycleBin.add(basic);
	}

	/**
	 * 把若干张牌丢到弃牌堆
	 */
	public void putBasic2recycle(List<Basic> basics) {
		for (Basic basic : basics) {
			putBasic2recycle(basic);
		}
	}

	/**
	 * 从上面获取1张牌，如果牌不够则把弃牌堆的所有牌拿来，如果还是没有[吕蒙把所有牌全部拿手里]，返回null
	 */
	public Basic getOutOneBasic() {
		if (basics.size() == 0 && recycleBin.size() == 0) {
			return null;
		}
		if (basics.size() == 0) {
			basics.addAll(recycleBin);
			recycleBin.clear();
			shuffleBasic();
		}
		return basics.remove(0);
	}

	/**
	 * 曹操+刘备+孙权 + 2随机
	 * 
	 * @return
	 */
	public List<General> getOutZhuGongRandomGeneral() {
		// 曹操+刘备+孙权 + 2随机
		List<General> result = new ArrayList<General>();
		result.add((General) getOutGeneral(CaoCao.class));
		result.add((General) getOutGeneral(LiuBei.class));
		result.add((General) getOutGeneral(SunQuan.class));
		result.add(getOutRandomGeneral());
		result.add(getOutRandomGeneral());
		return result;
	}

	public <T> T getOutGeneral(Class<? extends General> clazz) {
		for (General general : generals) {
			if (general.getClass() == clazz) {
				generals.remove(general);
				return (T) general;
			}
		}
		return null;
	}

	public void addGeneral(General general) {
		general.setCharacter(null);
		generals.add(general);
	}

	/**
	 * 随机将领
	 * 
	 * @return
	 */
	public List<General> getOutRandomGenerals(int num) {
		List<General> result = new ArrayList<General>();
		for (int i = 0; i < num; i++) {
			result.add(getOutRandomGeneral());
		}
		return result;
	}

	/**
	 * 随机将领
	 * 
	 * @return
	 */
	public General getOutRandomGeneral() {
		int size = generals.size();
		return size == 0 ? null : generals.remove(new Random().nextInt(size));
	}

	public ServerCardManager(ServerInstance instance) {
		this.instance = instance;
	}

	public ServerInstance getInstance() {
		return instance;
	}

	public void setInstance(ServerInstance instance) {
		this.instance = instance;
	}

	public List<Basic> getBasics() {
		return basics;
	}

	public List<Basic> getRecycleBin() {
		return recycleBin;
	}

	public List<General> getGenerals() {
		return generals;
	}
}
